package xiyuan.view.distance;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import xiyuan.data.DatabaseUtil;
import xiyuan.exception.NoKeywordsException;
import xiyuan.keywords.KeywordsGenerator;
import xiyuan.keywords.tfidf.KeyWord;
import xiyuan.localio.LocalWriter;
import xiyuan.weibo.UserInfo;
import xiyuan.weibo.WeiboUtil;
import xiyuan.view.data.ViewInformation;
import xiyuan.view.data.WeiboUser;

public class DistanceGenerator {
	public static ViewInformation getViewInfo(long uid, String searchTag) {

		ViewInformation vi = new ViewInformation();
		
		List<Long> friends = WeiboUtil.getFriendsByUID(uid);
		Map<String, Double> allFriendsKeyword = new HashMap<String, Double>();

		Map<Long, List<Double>> distanceMap = new HashMap<Long, List<Double>>();

		// store a map of keywords for display purpose
		Map<Long, List<KeyWord>> keywordMap = new HashMap<Long, List<KeyWord>>();

		for (long uidF : friends) {
			// when uid is equal to 2807910577, the query returns null
			// so i decided to skip it
			if (uidF == 2807910577L)
				continue;
			// if keywords for uid exist in db and that
			// the date is reasonable, get the list of keywords
			// straight from the database
			List<KeyWord> keywords;
			if (DatabaseUtil.userExist(uidF)) {
				keywords = DatabaseUtil.getKeywordByUID(uidF);
			} else {
				// otherwise, get keyword by querying
				keywords = KeywordsGenerator.generateKeyword(uidF);
			}

			// store keyword info for each user
			keywordMap.put(uidF, keywords);

			if (keywords == null)
				continue;

			// put keyword into a map of all friends
			for (KeyWord keyword : keywords) {
				String word = keyword.getWord();
				// ignore words with one character
				if (word.length() <= 1)
					continue;
				if (allFriendsKeyword.containsKey(word)) {
					allFriendsKeyword.put(word, allFriendsKeyword.get(word)
							+ keyword.getValue());
				} else
					allFriendsKeyword.put(word, keyword.getValue());
			}

			searchTag = "大学";// 这是正在查询的tag String，给出的是根据wordlist得到的
								// 联系人与这个tag String的distance

			// write to database
			if (keywords != null) {
				double distance;
				try {
					distance = NormalizedDistance.getDistanceByListAndTag(
							keywords, searchTag);
					LinkedList<Double> tmp = new LinkedList<Double>();
					tmp.add(distance);
					distanceMap.put(uidF, tmp);
					LocalWriter.writeDistance("distance.txt", distance, uidF);
				} catch (NoKeywordsException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		// generate the three additional tags
		List<KeyWord> allFriendsKeywordList = new ArrayList<KeyWord>();
		for (Entry<String, Double> keyword : allFriendsKeyword.entrySet()) {
			KeyWord word;
			allFriendsKeywordList.add(word = new KeyWord(keyword.getKey(),
					keyword.getValue()));
			System.out.println(word);
		}
		Collections.sort(allFriendsKeywordList);
		String[] addiKeys = new String[] {
				allFriendsKeywordList.get(0).getWord(),
				allFriendsKeywordList.get(1).getWord(),
				allFriendsKeywordList.get(2).getWord() };
		System.out.println(addiKeys[0] + "  " + addiKeys[1] + "  "
				+ addiKeys[2]);

		// get distance value for all additional tags
		for (long uidF : friends) {
			// when uid is equal to 2807910577, the query returns null
			// so i decided to skip it
			if (uidF == 2807910577L)
				continue;
			List<KeyWord> keywords = keywordMap.get(uidF);
			for (String checkTag : addiKeys) {
				if (keywords != null && keywords.size() >= 0) {
					double distance;
					try {
						distance = NormalizedDistance.getDistanceByListAndTag(
								keywords, checkTag);
						distanceMap.get(uidF).add(distance);
						LocalWriter.writeDistance("distance_"+checkTag+".txt", distance, uidF);
					} catch (NoKeywordsException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}

		vi.setAddiTags(addiKeys);
		vi.setSearchTag(searchTag);
		List<WeiboUser> users;
		vi.setUsers(users = new LinkedList<WeiboUser>());
		// prepare data for viewing
		for (long uidF : friends) {
			UserInfo ui = new UserInfo(uidF);
			WeiboUser tmp = new WeiboUser();
			tmp.setUid(uidF);
			tmp.setUsername(ui.getUsername());
			if (!keywordMap.containsKey(uidF) ||
					!distanceMap.containsKey(uidF))
				continue;
			tmp.setKeywords(keywordMap.get(uid).toArray(new String[0]));
			tmp.setDistance(distanceMap.get(uid).toArray(new Double[0]));
			users.add(tmp);
		}
		return null;
	}
}
